package com.android.common.image;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;

import com.android.common.App;
import com.android.common.asyntask.AsyncTask;
import com.android.common.image.i.BitmapConvertor;
import com.android.common.util.NumberUtil;
import com.android.common.util.StringUtil;

public class ImageLoader {
	private static ImageLoader instance;

	private static String TAG = "ImageLoader";

	private final static int NONE = -1;

	private static int TAG_KEY_ATTRIBUTE = "IMAGE_ATTRIBUTE".hashCode();

	private final static LinkedBlockingQueue<ImageView> toResumeImageViewQueue = new LinkedBlockingQueue<ImageView>(
			64);

	private AtomicBoolean enabled = new AtomicBoolean(true);// 加载图片是否开启

	public static ImageLoader getInstance() {
		if (instance == null) {
			instance = new ImageLoader();
		}
		return instance;
	}

	public void load(String url, ImageView imageView) {
		load(url, imageView, NONE, NONE, null);
	}

	public void load(String url, ImageView imageView, BitmapConvertor convertor) {
		load(url, imageView, NONE, NONE, convertor);
	}

	public void load(String url, ImageView imageView, int def,
			BitmapConvertor convertor) {
		load(url, imageView, def, NONE, convertor);
	}

	public void load(String url, ImageView imageView, int def, int error,
			BitmapConvertor convertor) {
		if (imageView == null) {
			return;
		}
		// 设置loading图标
		def = NumberUtil.defaultIfValue(def, NONE, App.DISPLAY.DEFAULT_IMG);
		// 设置出错图标
		error = NumberUtil.defaultIfValue(error, NONE, def);

		// 设置默认图标
		imageView.setImageResource(def);

		if (StringUtil.isBlank(url)) {
			return;
		}

		// 将IMAGE属性塞入tag
		ImageAttribute attr = new ImageAttribute(url, def, error,
				imageView.getWidth(), convertor);
		downloadImage(imageView, attr);
	}

	public void downloadImage(ImageView imageView, ImageAttribute attr) {
		if (imageView == null || attr == null) {
			return;
		}
		imageView.setTag(TAG_KEY_ATTRIBUTE, attr);

		if (StringUtil.isBlank(StringUtil.objectToString(attr.url))) {// 设置出错图标
			attr.url = attr.errorIcon;
			setImageDrawable(imageView);
			return;
		}

		if (!enabled.get()) {// 暂停状态不加载图片
			addToWaitQueue(imageView);
			return;
		}
		setImageDrawable(imageView);
	}

	public Drawable getDrawable(ImageAttribute att) {
		return DrawableFactory.getInstance().create(att);
	}

	private void setImageDrawable(ImageView v) {
		new ImageLoaderAsyncTask().execute(v);
	}

	private class ImageLoaderAsyncTask extends
			AsyncTask<ImageView, Void, Drawable> {
		ImageView view;

		@Override
		protected Drawable doInBackground(ImageView... params) {
			view = params[0];
			ImageAttribute att = (ImageAttribute) view
					.getTag(TAG_KEY_ATTRIBUTE);
			if (att != null) {
				return getDrawable(att);
			}
			return null;
		}

		@Override
		protected void onFinishExecute(Drawable result) {
			super.onFinishExecute(result);
			if (result != null) {
				view.setImageDrawable(result);
			}
		}

	}

	public void pause() {
		enabled.set(false);
	}

	public void resume() {
		enabled.set(true);
		ImageView v = null;
		while (enabled.get() && (v = toResumeImageViewQueue.poll()) != null) {
			if (isVisibility(v)) {
				downloadImage(v, (ImageAttribute) v.getTag(TAG_KEY_ATTRIBUTE));
			}
		}
	}

	public static class ImageAttribute {
		public Object url;
		public int loadingIcon;
		public int errorIcon;
		public int width;
		public BitmapConvertor convertor;

		public ImageAttribute(Object url, int loadingIcon, int errorIcon,
				int width, BitmapConvertor convertor) {
			this.url = url;
			this.loadingIcon = loadingIcon;
			this.errorIcon = errorIcon;
			this.width = width;
			this.convertor = convertor;
		}

		public String getUrl() {
			return StringUtil.objectToString(url);
		}
	}

	public static class ImageLoadOnScrollListenter implements OnScrollListener {

		private Context mContext;

		public ImageLoadOnScrollListenter(Context context) {
			mContext = context;
		}

		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			if (scrollState == SCROLL_STATE_IDLE) {// list停止滚动时加载图片
				ImageLoader.getInstance().resume();
			} else {
				ImageLoader.getInstance().pause();
			}
		}

		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
		}
	}

	/**
	 * 判断一个view是否可见
	 * 
	 * @param v
	 * @return
	 */
	private boolean isVisibility(ImageView v) {
		if ((v == null)
				|| (v.getTop() < 0 && Math.abs(v.getTop()) >= v.getHeight())) {
			return false;
		}

		return v.hasWindowFocus() && v.getVisibility() == View.VISIBLE
				&& v.isShown();
	}

	private synchronized void addToWaitQueue(ImageView v) {
		if (toResumeImageViewQueue.contains(v)) {
			toResumeImageViewQueue.remove(v);
		}
		if (!toResumeImageViewQueue.offer(v)) {
			toResumeImageViewQueue.poll();
			toResumeImageViewQueue.offer(v);
		}
	}

	public Drawable addQueue(Bitmap b) {
		return DrawableFactory.getInstance().addQueue(b);
	}

}
